#include "Function.hpp"
#include "Module.hpp"
#include "HelperFunctions.hpp"

namespace lua
{

Function::Function(lua_registryIndex luaFunc) : 
	mLuaRef(luaFunc),
	mModule(Module::currentModule)
{
	
}

void Function::unref()
{ 
	luaL_unref(mModule->getLuaVM(), LUA_REGISTRYINDEX, mLuaRef); 
}

void Function::operator()(lua::Args args)
{
	lua_rawgeti(mModule->getLuaVM(), LUA_REGISTRYINDEX, mLuaRef);
	lua::move(mModule->getLuaVM(), -(args.getNumArgs()+1));
	int status = lua_pcall(mModule->getLuaVM(), args.getNumArgs(), LUA_MULTRET, 0);
	report_errors(mModule->getLuaVM(), status);
}

bool Function::operator==(lua::Function &other)
{
	lua_rawgeti(mModule->getLuaVM(), LUA_REGISTRYINDEX, mLuaRef);
	lua_rawgeti(other.mModule->getLuaVM(), LUA_REGISTRYINDEX, other.mLuaRef);
	if(lua_topointer(mModule->getLuaVM(), -2) == lua_topointer(mModule->getLuaVM(), -1))
	{
		lua_remove(mModule->getLuaVM(), -1);
		lua_remove(mModule->getLuaVM(), -1);
		return true;
	}
	lua_remove(mModule->getLuaVM(), -1);
	lua_remove(mModule->getLuaVM(), -1);
	return false;
}

Module* Function::getModule()
{
	return mModule;
}

}